package com.xishu.service;

import com.xishu.aop.Validator;
import com.xishu.bo.image.ImageSize;
import com.xishu.dao.jpa.CompanyDao;
import com.xishu.entity.AbstractEntity;
import com.xishu.entity.Company;
import com.xishu.entity.User;
import com.xishu.entity.customer.CompanyConfig;
import com.xishu.entity.customer.VipLevel;
import com.xishu.entity.customer.VipRenewEmailTemplate;
import com.xishu.entity.customer.VipRenewMode;
import com.xishu.entity.plat.UserCompanyMapping;
import com.xishu.entity.shop.DiscountTicket;
import com.xishu.entity.shop.Shop;
import com.xishu.entity.shop.TouchDevice;
import com.xishu.response.VerifyUtil;
import com.xishu.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

public class CompanyService implements Tools {
    private static CompanyService instance = new CompanyService();
    private CommonService commonService = CommonService.getInstance();
    private static Logger logger = LoggerFactory.getLogger(CompanyService.class);

    private CompanyService() {
    }

    public static CompanyService getInstance() {
        return instance;
    }

    /**
     * 查询公司
     *
     * @param companyId
     * @return
     * @throws Exception
     */
    public Company findCompanyById(Long companyId) throws Exception {
        Company companyRequest = new Company();
        companyRequest.setId(companyId);

        Company company = null;
        try {
            company = CommonService.getInstance().findEntity(companyRequest, true);
        } catch (Exception e) {
            logger.error("e", e);
            //直接读
            company = CommonService.getInstance().findEntity(companyRequest, false);
        }

        if (company.getCompanyConfig() == null) {
            CompanyConfig companyConfig = new CompanyConfig();
            company.setCompanyConfig(companyConfig);
        }

        commonService.setDefaultValue(company.getCompanyConfig());

        return company;
    }

    /**
     * 通过名称查询公司
     *
     * @param name
     * @return
     */
    public Company findCompanyByName(String name) {
        CompanyDao companyDao = BeanUtil.getBean(CompanyDao.class);
        return companyDao.findByName(name);
    }

    /**
     * 下载餐桌的LOGO文件，并且变成100x100大小的图片
     *
     * @param companyId
     * @return
     */
    public File getCompanyLogoForQrCode(Long companyId) throws Throwable {
        CommonService commonService = CommonService.getInstance();
        Company company = commonService.findEntity(companyId, Company.class);
        String companyLogo = company.getCompanyLogo();
        File file = ObjectService.getInstance().downloadFile(companyLogo);
        //修改大小
        return ImgUtil.resize(file, new ImageSize(100, 100));
    }

    /**
     * 通过账号ID查询公司
     *
     * @param userId
     * @return
     * @throws Exception
     */
    public Company findCompanyByUserId(Long userId) throws Exception {
        List<UserCompanyMapping> userCompanyMappingList = MappingService.getInstance().findUserCompanyMappingByUserId(userId);

        if (isEmpty(userCompanyMappingList)) {
            return null;
        }

        //返回第一个
        UserCompanyMapping mapping = userCompanyMappingList.get(0);
        Long companyId = mapping.getCompanyId();

        Company company = CommonService.getInstance().findEntity(companyId, Company.class);
        return company;
    }

    /**
     * 通过分店ID来查询餐厅
     *
     * @param shopId
     * @return
     */
    public Company findCompanyByShopId(Long shopId) throws Exception {
        Shop shop = ShopService.getInstance().findShopById(shopId);
        return CommonService.getInstance().findEntity(shop.getCompanyId(), Company.class);
    }

    /**
     * 获取餐厅的名称
     *
     * @param company
     * @param zh
     * @return
     */
    public String getCompanyName(Company company, boolean zh) {
        if (zh) {
            return company.getName_zh();
        } else {
            return company.getName_en();
        }
    }


    /**
     * 查询在线的触摸屏
     *
     * @param companyId
     * @return
     */
    public List<TouchDevice> findOnLineTouchDeviceByCompanyId(Long companyId) {
        TouchDevice touchDevice = new TouchDevice();
        touchDevice.setCompanyId(companyId);

        List<TouchDevice> touchDeviceList = commonService.searchAll(touchDevice);
        return touchDeviceList.stream().filter(t -> ShopService.getInstance().isTouchDeviceOnline(t)).collect(Collectors.toList());
    }

    /**
     * 如果没有设置过，采用默认值
     *
     * @param company
     * @return
     */
    public int getLimitOnlineTouchDeviceNumber(Company company) {
        if (company == null) {
            return 0;
        }

        if (company.getOnlineTouchDeviceNumber() == null) {
            return 0;
        }

        return getInt(company.getOnlineTouchDeviceNumber());
    }

    /**
     * 删除跟公司相关的数据
     *
     * @param companyId
     * @param tClass
     */
    public <T extends AbstractEntity> void delete(Long companyId, Class<T> tClass) throws Exception {
        T instance = (T) tClass.newInstance();
        Field shopIdField = ClassUtil.getInstance().getField(tClass, "companyId");
        if (shopIdField == null) {
            logger.info("can not find the shopId field for class {}", tClass.getName());
            return;
        }

        shopIdField.set(instance, companyId);
        instance.setEntity(true);
        List<T> list = commonService.searchAll(instance);
        for (T t : list) {
            t.setFlagDelete(true);
            commonService.save(t);
        }
    }

    /**
     * 当前用户是否拥有修改公司的权限
     *
     * @param user
     * @param companyId
     * @return
     */
    public boolean ownCompany(User user, Long companyId) {
        if (user == null) {
            logger.info("user is null");
            return false;
        }

        if (companyId == null) {
            logger.info("company id is null");
            return false;
        }

        Validator validator = new Validator();
        boolean shopManager = validator.isShopManager(user);
        if (!shopManager) {
            return false;
        }

        if (getBoolean(user.getAdmin())) {
            return true;
        }

        if (getBoolean(user.getPlatManager()) || getBoolean(user.getCompanyManager())) {
            try {
                UserCompanyMapping companyMapping = MappingService.getInstance().findUserCompanyMapping(user.getId(), companyId);
                return companyMapping != null;
            } catch (Exception e) {
                logger.error("e", e);
                return false;
            }
        }

        return equals(user.getCompanyId(), companyId);
    }

    /**
     * 判断当前用户是否可以操作公司
     *
     * @param companyId
     * @return
     * @throws Exception
     */
    public boolean ownCompany(Long companyId) throws Exception {
        return ownCompany(ServletUtil.getUser(), companyId);
    }

    /**
     * 通过分店ID来判断是否可以操作公司
     *
     * @param shopId
     * @return
     */
    public boolean ownCompanyByShopId(Long shopId) throws Exception {
        Shop shop = ShopService.getInstance().findShopById(shopId);
        return ownCompany(shop.getCompanyId());
    }

    /**
     * 判断当前用户是否可以操作公司
     *
     * @param abstractEntity
     * @return
     */
    public boolean ownCompany(AbstractEntity abstractEntity) throws Exception {
        Optional<AbstractEntity> abstractEntityOptional = commonService.searchOneOptional(abstractEntity);
        VerifyUtil.verify(() -> abstractEntityOptional.isPresent());
        Field companyIdField = ClassUtil.getInstance().getField(abstractEntity.getClass(), "companyId");
        Long companyId = (Long) companyIdField.get(abstractEntityOptional.get());
        return ownCompany(companyId);
    }

    /**
     * 是否拥有会员级别的权限
     *
     * @param vipLevelId
     * @return
     */
    public boolean ownVipLevel(Long vipLevelId) throws Exception {
        Optional<VipLevel> vipLevelOptional = commonService.searchOneOptional(vipLevelId, VipLevel.class);
        if (!vipLevelOptional.isPresent()) {
            logger.info("can not find the vip level");
            return false;
        }

        return ownCompany(vipLevelOptional.get().getCompanyId());
    }

    /**
     * 是否拥有该TICKET
     *
     * @param ticketId
     * @return
     */
    public boolean ownTicket(Long ticketId) {
        try {
            Optional<DiscountTicket> discountTicketOptional = commonService.searchOneOptional(ticketId, DiscountTicket.class);
            if (!discountTicketOptional.isPresent()) {
                return false;
            }

            return ownCompany(discountTicketOptional.get().getCompanyId());
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 查询公司的付费模式
     *
     * @param companyId
     * @return
     */
    public VipRenewMode findVipRenewMode(Long companyId) {
        VipRenewMode vipRenewMode = new VipRenewMode();
        vipRenewMode.setCompanyId(companyId);
        vipRenewMode.setEntity(true);
        return commonService.searchOne(vipRenewMode);
    }

    /**
     * 创建一个空的付费模式
     *
     * @param companyId
     * @return
     */
    public VipRenewMode createRenewMode(Long companyId) throws Exception {
        VipRenewMode vipRenewMode = new VipRenewMode();
        vipRenewMode.setCompanyId(companyId);
        commonService.createObject(vipRenewMode);
        return vipRenewMode;
    }

    /**
     * 查询餐厅公司续费模板
     *
     * @param companyId
     * @return
     */
    public VipRenewEmailTemplate findVipRenewEmailTemplate(Long companyId) {
        VipRenewEmailTemplate vipRenewEmailTemplate = new VipRenewEmailTemplate();
        vipRenewEmailTemplate.setCompanyId(companyId);
        vipRenewEmailTemplate.setEntity(true);
        return commonService.searchOne(vipRenewEmailTemplate);
    }

    /**
     * 创建一个空的续费模板
     *
     * @param companyId
     * @return
     */
    public VipRenewEmailTemplate createVipRenewEmailTemplate(Long companyId) throws Exception {
        VipRenewEmailTemplate vipRenewEmailTemplate = new VipRenewEmailTemplate();
        vipRenewEmailTemplate.setCompanyId(companyId);
        commonService.createObject(vipRenewEmailTemplate);
        return vipRenewEmailTemplate;
    }
}
